#include <stdio.h>	// printf(), putchar()
#include <conio.h>	// getch()
#include <time.h>	// clock()
#include <windows.h>// Sleep()

#include "linkedlist.h"
#include "vector.h"

#define SCREEN_WIDTH	80

void printchar(char c)
{
	int color = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED ;
	switch(c)
	{
	case '\0':	color = FOREGROUND_BLUE;					c = '0';	break;
	case '\a':	color = FOREGROUND_RED | BACKGROUND_BLUE;	c = 'a';	break;
	case '\b':	color = FOREGROUND_RED | FOREGROUND_BLUE;	c = 'b';	break;
	case '\t':	color = FOREGROUND_RED | FOREGROUND_GREEN;	c = 't';	break;
	case '\n':	color = FOREGROUND_GREEN;					c = 'n';	break;
	case '\r':	color = FOREGROUND_BLUE | FOREGROUND_GREEN;	c = 'r';	break;
	case -1:	color = FOREGROUND_RED ;					c = 'e';	break;
	}
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
	printf("%c", c);
	// reset to standard color after we're done
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 
		FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
}

void draw(char * ptr)
{
	// top left corner of the screen
	COORD pos = {0,0};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
	for(int i = 0; i < 1600; ++i)
	{
		printchar(ptr[i]);
	}
	int * intPtr = (int*)ptr;
	printf("@location 0x%08x\n", ptr);
	printf("int  value: %12d\n", *intPtr);
	printf("hex  value: 0x%08x\n", *intPtr);
	printf("char value: %4d", *ptr);
}

void moveCursor(char keyInput, char * & ptr, Vector & history)
{
	switch(keyInput)
	{
	case 'w':	ptr -= SCREEN_WIDTH;	break;
	case 'a':	ptr -= 1;				break;
	case 's':	ptr += SCREEN_WIDTH;	break;
	case 'd':	ptr += 1;				break;
	case ' ':	*ptr = 0;				break;
	case '\n':	case '\r':{
		char * oldPtr = ptr;
//		ptr = (char*)*((int*)ptr);
		// or
//		int * intPtr = (int*)ptr;
//		ptr = (char*)*intPtr;
		// or
//		char ** nextPtr = (char**)ptr;
//		ptr = *nextPtr;
		// or
		ptr = *((char**)ptr);
		// remember where we are departing from
		history.add((int)oldPtr);
		break;}
	case '\b':
		// if we CAN go back to where we were
		if(history.size() > 0)
		{
			// go back to where we were
			ptr = (char*)history.get(history.size()-1);
			// allow us to go back to where we were before this
			history.setSize(history.size()-1);
		}
	}
}

int main(int argc, char ** argv)
{
	// initialization
	bool running = true;
	int input = 0, iterations = 0;
	time_t now, then = clock(), soon, timeOfLastIteration;
	const int FPS = 1;
	const int DELAY = 10000;///FPS;
	int someVariable = 5;
	LinkedList list;
	list.m_data = 1;
	list.add(5);
	list.add(10);
	list.add(8);
	list.add(7);
	char * ptr = (char*)&list;
	Vector history;
	ptr = (char*)&history;
	// the game loop
	while(running)
	{
		// get input
		if(kbhit())
		{
			input = getch();
			moveCursor(input, ptr, history);
			running = (input != 'q');
		}
		else
		{
			// calculate time
			now = clock();
			timeOfLastIteration = now - then;
			then = now;
			// draw
			draw(ptr);
			// throttle code
			soon = now + DELAY;
			while(!kbhit() && clock() < soon)
				Sleep(1);
			// update process
			iterations++;
		}
	}
	// release
	return 0;
}